/*
 * 
 */
package com.gidas.client;

//import com.gidas.classes.FileUp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.rpc.AsyncCallback; //import com.google.gwt.user.client.ui.Button;

import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;

import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DecoratedStackPanel;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RadioButton;

import com.google.gwt.user.client.ui.TextArea;

import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.maps.client.InfoWindow;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;

import com.google.gwt.maps.client.InfoWindowContent.InfoWindowTab;
import com.google.gwt.maps.client.control.LargeMapControl;
import com.google.gwt.maps.client.control.MapTypeControl;
import com.google.gwt.maps.client.event.MapClickHandler;
import com.google.gwt.maps.client.event.MarkerClickHandler;
import com.google.gwt.maps.client.event.MarkerDragEndHandler;
import com.google.gwt.maps.client.event.MarkerDragStartHandler;
import com.google.gwt.maps.client.geocode.DirectionQueryOptions;
import com.google.gwt.maps.client.geocode.DirectionResults;
import com.google.gwt.maps.client.geocode.Directions;
import com.google.gwt.maps.client.geocode.DirectionsCallback;
import com.google.gwt.maps.client.geocode.DirectionsPanel;
import com.google.gwt.maps.client.geocode.Geocoder;
import com.google.gwt.maps.client.geocode.LatLngCallback;
import com.google.gwt.maps.client.geocode.LocationCallback;
import com.google.gwt.maps.client.geocode.Placemark;
import com.google.gwt.maps.client.geocode.Route;
import com.google.gwt.maps.client.geocode.Waypoint;
import com.google.gwt.maps.client.geom.Bounds;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.geom.LatLngBounds;
import com.google.gwt.maps.client.geom.Point;
import com.google.gwt.maps.client.geom.Size;
import com.google.gwt.maps.client.overlay.Icon;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.maps.client.overlay.Polyline;

// TODO: Auto-generated Javadoc
/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
@SuppressWarnings("deprecation")
public class GM implements EntryPoint, MapAdminListener {
	
	/** The message displayed to the user when the server cannot be reached or returns an error. */

	private MapWidget map;
	
	private LatLngBounds bounds;
	
	/** The meniu w. */
	private DecoratedStackPanel meniuW;
	
	/** The menu width. */
	private int menuWidth = 200;

	/** The admin. */
	private AdminPanel admin = new AdminPanel();
	
	/** The admin panel. */
	private ScrollPanel adminPanel;
	
	/** The user menu. */
	private HorizontalPanel userMenu;
	
	/** The menu and map panel. */
	private HorizontalPanel menuAndMapPanel;
	
	/** The current main window. */
	private int currentMainWindow = -1;

	// meniu
	// ScrollPanel filtersPanel = new ScrollPanel();
	/** The filters vertical panel. */
	VerticalPanel filtersVerticalPanel = new VerticalPanel();

	// login
	/** The login info. */
	private LoginInfo loginInfo = new LoginInfo();
	
	/** The login label. */
	private Label loginLabel = new Label("Sveiki atvykę! ");
	
	/** The sign in link. */
	private Anchor signInLink = new Anchor("Prisijungti");
	
	/** The sign out link. */
	private Anchor signOutLink = new Anchor("Atsijungti");
	
	/** The user info panel. */
	private HorizontalPanel userInfoPanel = new HorizontalPanel();

	// geocoding
	/** The geocoder. */
	private Geocoder geocoder = new Geocoder();
	
	/** The marker. */
	private Marker marker = null;

	// markers
	/** The new poi window. */
	private InfoWindowContent newPoiWindow = null;
	
	/** The object adress tx bx. */
	private TextBox objectAdressTxBx = null;
	
	/** The poi lat tx bx. */
	private TextBox poiLatTxBx = null;
	
	/** The poi lng tx bx. */
	private TextBox poiLngTxBx = null;
	
	/** The new object handler added. */
	private boolean newObjectHandlerAdded = false;
	
	/** The start marker. */
	private Marker startMarker = null;
	
	/** The end marker. */
	private Marker endMarker = null;
	// add new point by clicking on map
	/** The search poi by click btn. */
	private Button searchPoiByClickBtn = null;
	
	/** The add poi map handler. */
	private MapClickHandler addPoiMapHandler = null;
	
	/** The add start map handler. */
	private MapClickHandler addStartMapHandler = null;
	
	/** The add end map handler. */
	private MapClickHandler addEndMapHandler = null;
	
	/** The place start btn. */
	Button placeStartBtn = null;
	
	/** The place end btn. */
	Button placeEndBtn = null;
	
	
	/** The Poi service. */
	private final PoiServiceAsync PoiService = GWT.create(PoiService.class);
	
	/** The object type list. */
	List<ObjectTypeSerializable> objectTypeList = null;

	// route
	/** The route. */
	private UserRoute route = new UserRoute();
	
	private VerticalPanel poiPanel = new VerticalPanel();
	
	private Waypoint[] waypoints = null;
	
	//TODO clean me
	private MapWidget tmpMap = new MapWidget();
	private DirectionsPanel directionsPanel = new DirectionsPanel();

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {

		checkIfLoggedIn();
		LatLng KaunasCity = LatLng.newInstance(54.89714423283752,
				23.9132022857666);
		// Open a map centered on Kaunas, Lithuania
		bounds = LatLngBounds.newInstance();
		bounds.extend(KaunasCity);
		
		map = new MapWidget(KaunasCity, 13);
		map.addControl(new LargeMapControl());
		map.addControl(new MapTypeControl());
		map.setScrollWheelZoomEnabled(true);

		adminPanel = admin.getPanel();
		admin.addSignInListener(this);

		userMenu = new HorizontalPanel();
		userMenu.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);

		Hyperlink goToAbout = new Hyperlink("Apie projektą", "about");
		Hyperlink goToContacts = new Hyperlink("Kontaktai", "contacts");

		Hyperlink goToAdminPanelBtn = new Hyperlink("Administravimas", "admin");
		goToAdminPanelBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if(loginInfo.getIsAdmin())
				{
				changeMainWindow(1);
				}
				else
				{
					Window.alert("Šis skiltis skirta administratoriui ;) jei norite prisidėti prie projekto ar turite klausimų, rašykite tadasz@gmail.com");
				}
			}
		});
		userMenu.add(goToAbout);
		userMenu.add(goToContacts);

		userMenu.add(goToAdminPanelBtn);

		/*
		 * Button goToMapPanelBtn = new Button("Grizti i zemelapi");
		 * goToMapPanelBtn.addClickHandler(new ClickHandler() { public void
		 * onClick(ClickEvent event) { changeMainWindow(0); } });
		 * admin.add(goToMapPanelBtn);
		 */

		VerticalPanel holder = new VerticalPanel();

		holder.setWidth("250px");
		holder.setHeight("250px");
		holder.setHorizontalAlignment(HasAlignment.ALIGN_RIGHT);

		meniuW = new DecoratedStackPanel();

		// mainPanel = new CaptionPanel();

		Window.enableScrolling(false);

		Window.addWindowResizeListener(new WindowResizeListener() {
			public void onWindowResized(int x, int y) {
				resizeMe(x, y);
			}
		});

		int windowHeight = Window.getClientHeight();
		int windowWidth = Window.getClientWidth();

		meniuW.add(createFiltersPanel(200), "Filtrai");
		meniuW.add(createRoutePanel(), "Maršrutai");
		meniuW.add(createPoiPanel(), "Objektai");
		meniuW.add(createNewPoiPanel(), "Naujas objektas");

		// mainPanel.add(map);
		// mainPanel.setCaptionText("Zemelapis");

		menuAndMapPanel = new HorizontalPanel();
		menuAndMapPanel.add(meniuW);
		menuAndMapPanel.add(map);

		userMenu.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);

		DOM.setInnerHTML(RootPanel.get("Loading-Message").getElement(), "");

		RootPanel.get("map").add(menuAndMapPanel);
		RootPanel.get("userMenu").add(userMenu);
		resizeMe(windowWidth, windowHeight);
	}

	/**
	 * Resize me.
	 * 
	 * @param x the x
	 * @param y the y
	 */
	private void resizeMe(int x, int y) {
		int windowHeight = y - userMenu.getOffsetHeight() - 30;
		int windowWidth = x;
		int windowWidthMap = windowWidth - menuWidth;

		String mapWidthPx = windowWidthMap + "px";
		// String mainWidthPx = windowWidth + "px";
		String mapHeightPx = windowHeight + "px";
		String menuWidthPx = menuWidth + "px";

		String mainPanelWidthPx = windowWidth + "px";
		String mainPanelHeightPx = windowHeight + "px";

		menuAndMapPanel.setSize(mainPanelWidthPx, mainPanelHeightPx);
		adminPanel.setSize(mainPanelWidthPx, mainPanelHeightPx);
		// adminPanel.s
		map.setSize(mapWidthPx, mapHeightPx);
		meniuW.setSize(menuWidthPx, mainPanelHeightPx);

		userMenu.setWidth(x + "px");

	}

	/**
	 * Gets the poi types.
	 * 
	 * @return the poi types
	 */
	private void getPoiTypes() {
		PoiService
				.getPoiTypeService(new AsyncCallback<List<ObjectTypeSerializable>>() {

					public void onFailure(Throwable caught) {
						Window.alert(caught.toString());
					}

					public void onSuccess(List<ObjectTypeSerializable> result) {
						objectTypeList = new ArrayList<ObjectTypeSerializable>();
						objectTypeList = result;
						fillFiltersPanel();
					}

				});
	}

	/**
	 * Gets the poi.
	 * 
	 * @param filterList the filter list
	 * @param showOnlyConfirmed show only confirmed
	 * 
	 * @return the poi
	 */
	private void getPoi(List<String> filterList, Boolean showOnlyConfirmed) {
		PoiService.getPoiService(filterList, showOnlyConfirmed, 0, 50,
				new AsyncCallback<List<ObjectSerializable>>() {

					public void onFailure(Throwable caught) {
						Window.alert(caught.toString());

					}

					public void onSuccess(List<ObjectSerializable> result) {
						System.out.println("Results!");
						if (result.isEmpty() || result == null) {
							Window.alert("Tokių objektų nerasta...");

						} else {
							for (ObjectSerializable o : result) {

								System.out.println(o.getName() + ", rating="
										+ o.getRating() + ", objectType="
										+ o.getObjectType() + ", confirm="
										+ o.getConfirmed());
							}
							addMarkersToMap(result);
						}

					}

				});
	}

	/**
	 * Adds the poi.
	 * 
	 * @param object the object
	 */
	private void addPoi(ObjectSerializable object) {
		PoiService.addPoiService(object, new AsyncCallback<Boolean>() {

			public void onFailure(Throwable caught) {

				Window.alert(caught.toString());
			}

			public void onSuccess(Boolean result) {

				Window.alert("Įdėjo!");
			}

		});
	}

	/**
	 * Fill filters panel.
	 */
	private void fillFiltersPanel() {
		if (objectTypeList != null && !objectTypeList.isEmpty()) {
			for (ObjectTypeSerializable o : objectTypeList) {
				CheckBox objectTypeCheckBox = new CheckBox(o.getName());
				objectTypeCheckBox.setName(o.getEncodedKey());
				filtersVerticalPanel.add(objectTypeCheckBox);

			}
		}
	}

	/**
	 * Gets the icon.
	 * 
	 * @param type the type
	 * 
	 * @return the icon
	 */
	private Icon getIcon(String type) {
		// System.out.println("objectoTipas ='" + type + "'");
		// System.out.println(type.compareTo("bz") == 0);
		Icon icon = null;
		
		if (type.compareTo("start") == 0) {
			icon = Icon.newInstance("img/maps/icons/start.png");
			icon.setShadowURL("img/maps/icons/start_s.png");
			icon.setIconSize(Size.newInstance(32, 32));
			icon.setIconAnchor(Point.newInstance(16, 32));
		} else if (type.compareTo("stop") == 0) {
			icon = Icon.newInstance("img/maps/icons/stop.png");
			icon.setShadowURL("img/maps/icons/stop_s.png");
			icon.setIconSize(Size.newInstance(32, 32));
			icon.setIconAnchor(Point.newInstance(16, 32));
		} else if (type.compareTo("bz") == 0) {
			icon = Icon.newInstance("img/maps/icons/church.png");
			icon.setShadowURL("img/maps/icons/church_s.png");
			icon.setIconSize(Size.newInstance(32, 32));
			icon.setShadowSize(Size.newInstance(59, 32));
			icon.setIconAnchor(Point.newInstance(16, 16));
			icon.setInfoWindowAnchor(Point.newInstance(16, 0));
		} else if (type.compareTo("zo") == 0) {
			icon = Icon.newInstance("img/maps/icons/zoo.png");
			icon
					.setShadowURL("http://maps.google.com/mapfiles/kml/pal2/icon11s.png");
			icon.setIconSize(Size.newInstance(32, 32));
			icon.setShadowSize(Size.newInstance(59, 32));
			icon.setIconAnchor(Point.newInstance(16, 16));
			icon.setInfoWindowAnchor(Point.newInstance(16, 0));
		} else {
			return null;
		}
		/*
		 * var icon_baznycia = new GIcon(baseIcon,
		 * "http://maps.google.com/mapfiles/kml/pal2/icon11.png");
		 * icon_baznycia.shadow =
		 * "http://maps.google.com/mapfiles/kml/pal2/icon11s.png";
		 * icon_baznycia.infoWindowAnchor = new GPoint(16, 0);
		 * icon_baznycia.iconSize = new GSize(32, 32);
		 */
		return icon;
	}

	/**
	 * Adds the markers to map.
	 * 
	 * @param objectList the object list
	 */
	private void addMarkersToMap(List<ObjectSerializable> objectList) {
		map.clearOverlays();
		for (final ObjectSerializable o : objectList) {

			// TODO padaryti iconas
			LatLng coordinates = LatLng.newInstance(o.getLat(), o.getLng());

			MarkerOptions options = MarkerOptions.newInstance();
			Icon icon = getIcon(o.getObjectType());
			if (icon != null) {
				options.setIcon(icon);
			}

			final Marker newMarker = new Marker(coordinates, options);
			final VerticalPanel panel = new VerticalPanel();
			final InfoWindowContent content = new InfoWindowContent(panel);
			panel.add(new Label(o.getName()));
			panel.add(new Label("Reitingas " + o.getRating() + "/5"));
			TextArea description = new TextArea();
			description.setText(o.getDescription());
			panel.add(description);
			// TODO patikrinti ar neįtrauktas...
			final Button removeToRouteBtn = new Button("Šalint iš maršrutų",
					new ClickHandler() {

						public void onClick(ClickEvent event) {
							if (route.removeObject(o)) {
								getRoutes();
							}
							route.traceObjects();

						}
					});
			ClickHandler addHandler = new ClickHandler() {

				public void onClick(ClickEvent event) {
					if (route.addObject(o)) {
						getRoutes();
					}
					route.traceObjects();

				}

			};

			final Button addToRouteBtn = new Button("Į maršrutus", addHandler);

			panel.add(removeToRouteBtn);
			panel.add(addToRouteBtn);

			newMarker.addMarkerClickHandler(new MarkerClickHandler() {

				public void onClick(MarkerClickEvent event) {
					map.getInfoWindow().open(newMarker, content);
				}

			});
			map.addOverlay(newMarker);
			bounds.extend(newMarker.getLatLng());
				

		}
		mapFitBounds();

	}

	private void mapFitBounds()
	{
		map.setCenter(bounds.getCenter());
		map.setZoomLevel(map.getBoundsZoomLevel(bounds));
	}
	/**
	 * Adds the new poi marker.
	 * 
	 * @param point the point
	 * @param address the address
	 */
	private void addNewPoiMarker(LatLng point, String address) {
		removeMapClickHandler();
		// map.setCenter(point, 13);
		MarkerOptions options = MarkerOptions.newInstance();
		options.setDraggable(true);

		map.clearOverlays();

		marker = new Marker(point, options);

		map.addOverlay(marker);

		final InfoWindow info = map.getInfoWindow();
		newPoiWindow = displayAddNewPoi(point, address);

		info.open(marker, newPoiWindow);

		marker.addMarkerDragEndHandler(new MarkerDragEndHandler() {
			public void onDragEnd(MarkerDragEndEvent event) {
				info.open(marker, newPoiWindow);
				LatLng newCoordinates = marker.getLatLng();
				System.out.println(newCoordinates.getLatitude());
				poiLatTxBx.setText("" + newCoordinates.getLatitude());
				// poiLatTxBx.
				poiLngTxBx.setText("" + newCoordinates.getLongitude());
			}

		});

		marker.addMarkerDragStartHandler(new MarkerDragStartHandler() {
			public void onDragStart(MarkerDragStartEvent event) {
				info.setVisible(false);
			}
		});

		marker.addMarkerClickHandler(new MarkerClickHandler() {

			public void onClick(MarkerClickEvent event) {
				info.open(marker, newPoiWindow);
			}

		});
	}

	
	
	/**
	 * Adds the start marker.
	 * 
	 * @param point the point
	 */
	private void addStartMarker(LatLng point)
	{		
		if(startMarker!= null)
		{
			map.removeOverlay(startMarker);	
		}		
		MarkerOptions options = MarkerOptions.newInstance();
		options.setDraggable(true);
		Icon icon = getIcon("start");
		if (icon != null) {
			options.setIcon(icon);
		}
		startMarker = new Marker(point, options);
		map.addOverlay(startMarker);
		bounds.extend(startMarker.getLatLng());
		mapFitBounds();
	}
	
	/**
	 * Adds the end marker.
	 * 
	 * @param point the point
	 */
	private void addEndMarker(LatLng point)
	{
		if(endMarker != null)
		{
		map.removeOverlay(endMarker);
		}
		MarkerOptions options = MarkerOptions.newInstance();
		options.setDraggable(true);
		Icon icon = getIcon("stop");
		if (icon != null) {
			options.setIcon(icon);
		}
		endMarker = new Marker(point, options);
		map.addOverlay(endMarker);
		bounds.extend(startMarker.getLatLng());
		mapFitBounds();
	}
	
	/**
	 * Search address.
	 * 
	 * @param address the address
	 */
	private void searchAddress(final String address) {
		geocoder.getLatLng(address, new LatLngCallback() {
			public void onFailure() {
				Window.alert(address + " nerastas :/");
			}

			public void onSuccess(LatLng point) {
				addNewPoiMarker(point, address);
				/*
				 * map.setCenter(point, 13); MarkerOptions options =
				 * MarkerOptions.newInstance(); options.setDraggable(true);
				 * 
				 * map.clearOverlays();
				 * 
				 * 
				 * marker = new Marker(point,options);
				 * 
				 * map.addOverlay(marker);
				 * 
				 * final InfoWindow info = map.getInfoWindow(); newPoiWindow =
				 * displayAddNewPoi(point,address);
				 * 
				 * info.open(marker, newPoiWindow);
				 * 
				 * marker.addMarkerDragEndHandler(new MarkerDragEndHandler() {
				 * public void onDragEnd(MarkerDragEndEvent event) {
				 * info.open(marker, newPoiWindow); LatLng newCoordinates =
				 * marker.getLatLng();
				 * System.out.println(newCoordinates.getLatitude());
				 * poiLatTxBx.setText(""+newCoordinates.getLatitude());
				 * //poiLatTxBx.
				 * poiLngTxBx.setText(""+newCoordinates.getLongitude()); }
				 * 
				 * });
				 * 
				 * marker.addMarkerDragStartHandler(new MarkerDragStartHandler()
				 * { public void onDragStart(MarkerDragStartEvent event) {
				 * info.setVisible(false); } });
				 * 
				 * marker.addMarkerClickHandler(new MarkerClickHandler(){
				 * 
				 * public void onClick(MarkerClickEvent event) {
				 * info.open(marker, newPoiWindow); }
				 * 
				 * });
				 */

			}
		});
	}

	/**
	 * Gets the address.
	 * 
	 * @param coordinates the coordinates
	 * 
	 * @return the address
	 */
	private void getAddress(LatLng coordinates) {
		geocoder.getLocations(coordinates, new LocationCallback() {

			public void onFailure(int statusCode) {
				objectAdressTxBx.setText("Kaunas, ");
			}

			public void onSuccess(JsArray<Placemark> locations) {
				// TODO Auto-generated method stub
				for (int i = 0; i < locations.length(); ++i) {
					Placemark location = locations.get(i);
					if (location.getAddress() != null) {
						objectAdressTxBx.setText(location.getAddress());
						break;
					} else if (location.getCity() != null) {
						objectAdressTxBx.setText(location.getCity());
						break;
					} else if (location.getAdministrativeArea() != null) {
						objectAdressTxBx.setText(location
								.getAdministrativeArea()
								+ ", ");
						break;
					} else if (location.getCountry() != null) {
						objectAdressTxBx.setText(location.getCountry());
						break;
					} else {
						objectAdressTxBx.setText("Kaunas, ");
					}

				}

			}
		});
	}

	/**
	 * New poi by coordinates.
	 * 
	 * @param lat the lat
	 * @param lng the lng
	 */
	private void newPoiByCoordinates(String lat, String lng) {
		LatLng point = LatLng.newInstance(Double.parseDouble(lat), Double
				.parseDouble(lng));
		addNewPoiMarker(point, "Kaunas, ");
	}

	/**
	 * Display add new poi.
	 * 
	 * @param point the point
	 * @param address the address
	 * 
	 * @return the info window content
	 */
	private InfoWindowContent displayAddNewPoi(LatLng point, String address) {

		InfoWindowTab tabs[] = new InfoWindowTab[4];

		/***************************/
		/********* TAB - Vieta *******/
		VerticalPanel tabPlace = new VerticalPanel();
		tabPlace.setSpacing(4);
		tabPlace.add(new Label("Objekto adresas:"));

		HorizontalPanel addressPanel = new HorizontalPanel();
		objectAdressTxBx = new TextBox();
		objectAdressTxBx.setText(address);
		Button getAddressBtn = new Button("Gauti adresą", new ClickHandler() {

			public void onClick(ClickEvent event) {
				if (poiLatTxBx.getText().compareTo("") != 0
						&& poiLngTxBx.getText().compareTo("") != 0) {
					LatLng coordinates = LatLng.newInstance(Double
							.parseDouble(poiLatTxBx.getText()), Double
							.parseDouble(poiLngTxBx.getText()));
					getAddress(coordinates);
				}

			}

		});
		addressPanel.add(objectAdressTxBx);
		addressPanel.add(getAddressBtn);
		tabPlace.add(addressPanel);

		tabPlace.add(new Label("Koordinates:"));
		HorizontalPanel latPanel = new HorizontalPanel();
		latPanel.add(new Label("Lat:"));
		//
		poiLatTxBx = new TextBox();
		poiLatTxBx.setText("" + point.getLatitude());
		poiLatTxBx.setTitle("platuma");
		latPanel.add(poiLatTxBx);
		tabPlace.add(latPanel);

		HorizontalPanel lngPanel = new HorizontalPanel();
		lngPanel.add(new Label("Lng:"));
		poiLngTxBx = new TextBox();
		poiLngTxBx.setText("" + point.getLongitude());
		poiLngTxBx.setTitle("ilguma");
		lngPanel.add(poiLngTxBx);
		tabPlace.add(lngPanel);

		/***************************/
		/********* TAB - Info ********/
		VerticalPanel tabInfo = new VerticalPanel();
		tabInfo.setSpacing(4);

		tabInfo.add(new Label("Objekto pavadinimas:"));
		final TextBox objectNameTxBx = new TextBox();
		tabInfo.add(objectNameTxBx);

		tabInfo.add(new Label("Pasirinkite objekto tipą:"));
		final ListBox poiType = new ListBox(false);
		if (objectTypeList != null) {
			for (ObjectTypeSerializable o : objectTypeList) {
				poiType.addItem(o.getName(), o.getEncodedKey());
			}
		}

		tabInfo.add(poiType);

		tabInfo.add(new Label("Pasirinkite objekto lankymo laiką, min:"));
		final ArrayList<Integer> timeList = Constants.getTimeArray();
		final ListBox poiTime = new ListBox(false);
		poiTime.setSelectedIndex(-1);

		// padaryti kad kai pasirenka is objekto tipo irasytu atitinkama laika
		// int selectTime = 0;int i = 0;
		for (int s : timeList) {
			// if(s.compareTo(anotherString))
			poiTime.addItem("" + s);
		}
		tabInfo.add(poiTime);

		poiType.addChangeHandler(new ChangeHandler() {

			public void onChange(ChangeEvent event) {

				String key = poiType.getValue(poiType.getSelectedIndex());
				for (ObjectTypeSerializable o : objectTypeList) {

					if (o.getEncodedKey().compareTo(key) == 0) {

						int i = 0;
						for (int s : timeList) {
							if (s == o.getTakesTimeMinutes()) {

								poiTime.setSelectedIndex(i);
								break;
							}
							i++;
						}
						break;
					}
				}

			}

		});
		// need this to make sure onChange event works
		poiType.setSelectedIndex(-1);

		tabInfo.add(new Label("Įvertinkit objektą:"));
		ArrayList<String> ratingList = Constants.getRatingArray();
		final ListBox poiRating = new ListBox(false);
		for (String s : ratingList) {
			poiRating.addItem(s);
		}
		poiRating.setSelectedIndex(-1);
		tabInfo.add(poiRating);

		/***************************/
		/********* TAB - Data ********/
		VerticalPanel tabData = new VerticalPanel();
		// tabData.setSpacing(4);

		tabData.add(new Label("Įveskite objekto aprašymą:"));
		final TextArea area = new TextArea();
		// area.
		area.setSize("100%", "14em");
		area.setWidth("250px");
		// RichTextToolbar toobar = new RichTextToolbar(area);
		// RichTextToolbar toolbar = new RichTextToolbar(area);
		// tabData.add(toobar);
		tabData.add(area);
		// f

		/***************************/
		/********* TAB - Save ********/
		VerticalPanel tabSave = new VerticalPanel();
		tabSave.setSpacing(4);
		tabSave.add(new Button("Saugoti!", new ClickHandler() {

			public void onClick(ClickEvent event) {
				// check if all feelds are filled
				// poiLatTxBx;poiLngTxBx;objectNameTxBx;poiType!=-1;poiTime;poiRating;
				if (poiLatTxBx.getText().compareTo("") != 0
						&& poiLngTxBx.getText().compareTo("") != 0
						&& objectNameTxBx.getText().compareTo("") != 0
						&& poiType.getSelectedIndex() != -1
						&& poiTime.getSelectedIndex() != -1
						&& poiRating.getSelectedIndex() != -1) {
					ObjectSerializable object = new ObjectSerializable(
							objectNameTxBx.getText(), objectAdressTxBx
									.getText(), Double.parseDouble(poiLatTxBx
									.getText()), Double.parseDouble(poiLngTxBx
									.getText()), poiType.getValue(poiType
									.getSelectedIndex()), Integer
									.parseInt(poiTime.getValue(poiTime
											.getSelectedIndex())), Integer
									.parseInt(poiRating.getValue(poiRating
											.getSelectedIndex())),
							// TODO autorius pagal prisijungima nustatomas
							loginInfo.getEmailAddress(), 
							new Date(), area.getText(),
							// TODO tikrinti ar adminas idejo, jei ne adminas,
							// daryti kad nepatvirtintas
							loginInfo.getIsAdmin());
					/*
					 * String _name, String _address, Double _lat, Double _lng,
					 * String _objectType, int _time, int _rating, String
					 * _author, Date _creation, String description, Boolean
					 * _confirmed
					 */
					addPoi(object);
				} else {
					Window.alert("Negerai užpildyti laukai!");
				}

			}

		}));

		tabs[0] = new InfoWindowTab("Vieta", tabPlace);
		tabs[1] = new InfoWindowTab("Info", tabInfo);
		tabs[2] = new InfoWindowTab("Aprašymas", tabData);
		tabs[3] = new InfoWindowTab("Saugoti", tabSave);
		final InfoWindowContent content = new InfoWindowContent(tabs, 0);

		return content;
	}

	/**
	 * Creates the new poi panel.
	 * 
	 * @return the vertical panel
	 */
	private VerticalPanel createNewPoiPanel() {
		final VerticalPanel addPoiControlsPanel = new VerticalPanel();
		LoginServiceAsync loginService = GWT.create(LoginService.class);
		loginService.login(GWT.getHostPageBaseURL(),
				new AsyncCallback<LoginInfo>() {
					public void onFailure(Throwable error) {
					}

					public void onSuccess(LoginInfo result) {
						loginInfo = result;
						if (loginInfo.isLoggedIn()) {
							addPoiControlsPanel.add(new Label("Įveskite objekto adresą"));
							final TextBox poiAddressTxBx = new TextBox();
							poiAddressTxBx.setText("Kaunas, ");
							addPoiControlsPanel.add(poiAddressTxBx);
							Button searchPoiByAddressBtn = new Button("Ieškoti",
									new ClickHandler() {
										public void onClick(ClickEvent event) {
											searchAddress(poiAddressTxBx.getText());
										}
									});
							addPoiControlsPanel.add(searchPoiByAddressBtn);
							addPoiControlsPanel.add(new Label("arba koordinates:"));
					
							HorizontalPanel latPanel = new HorizontalPanel();
							latPanel.add(new Label("Lat:"));
							final TextBox newPoiLatTxBx = new TextBox();
							newPoiLatTxBx.setTitle("platuma");
					
							latPanel.add(newPoiLatTxBx);
							addPoiControlsPanel.add(latPanel);
					
							HorizontalPanel lngPanel = new HorizontalPanel();
							lngPanel.add(new Label("Lng:"));
							final TextBox newPoiLngTxBx = new TextBox();
							newPoiLngTxBx.setTitle("ilguma");
							lngPanel.add(newPoiLngTxBx);
							addPoiControlsPanel.add(lngPanel);
							Button searchPoiByCoordinatesBtn = new Button("Ieškoti",
									new ClickHandler() {
										public void onClick(ClickEvent event) {
											if (newPoiLatTxBx.getText().compareTo("") == 0
													|| newPoiLngTxBx.getText().compareTo("") == 0) {
												Window.alert("Neįvestos koordinatės");
											} else {
												newPoiByCoordinates(newPoiLatTxBx.getText(),
														newPoiLngTxBx.getText());
											}
										}
									});
							addPoiControlsPanel.add(searchPoiByCoordinatesBtn);
					
							addPoiControlsPanel.add(new Label("arba pažymėkite tašką žemėlapyje"));
					
							searchPoiByClickBtn = new Button("Žymėti");
							addPoiMapHandler = new MapClickHandler() {
					
								public void onClick(MapClickEvent event) {
									// TODO Add geocoding get address
									// http://code.google.com/p/gwt-google-apis/source/browse/trunk/maps/samples/hellomaps/src/com/google/gwt/maps/sample/hellomaps/client/ReverseGeocoderDemo.java
									if (event.getOverlay() != null) {
										return;
									}
									getAddress(event.getLatLng());
					
									addNewPoiMarker(event.getLatLng(), "Kaunas, ");
					
								}
							};
					
							searchPoiByClickBtn.addClickHandler(new ClickHandler() {
								public void onClick(ClickEvent event) {
									searchPoiByClickBtn.setText("Paspauskite ant žemėlapio");
									searchPoiByClickBtn.setEnabled(false);
									newObjectHandlerAdded = true;
									map.addMapClickHandler(addPoiMapHandler);
								}
					
							});
							addPoiControlsPanel.add(searchPoiByClickBtn);
					
							map.removeMapClickHandler(addPoiMapHandler);
						} else {
							HorizontalPanel pleaseLoginTextPanel = new HorizontalPanel();
							Anchor signInAnchor = new Anchor(); 
							signInAnchor.setHref(loginInfo.getLoginUrl());
							signInAnchor.setText("prisijungite,");
							pleaseLoginTextPanel.add(signInAnchor);						
							pleaseLoginTextPanel.add(new Label(" norėdami prisidėti prie turinio pildymo :) "));
						
							addPoiControlsPanel.add(pleaseLoginTextPanel);
						}
					}
				});

		
		if(loginInfo.isLoggedIn() == false)
		{
				//nerodom
		}
		else
		{					
			
		}
		return addPoiControlsPanel;

	}

	private VerticalPanel createPoiPanel()
	{
		final DisclosurePanel poiFilterPanel = new DisclosurePanel(
		"Nustatymai");
		
		poiFilterPanel.addOpenHandler(new OpenHandler<DisclosurePanel>() {

			public void onOpen(OpenEvent<DisclosurePanel> event) {
				VerticalPanel poiFilterContainer = new VerticalPanel();
				poiFilterContainer.add(new Label("Max laikas"));
				poiFilterContainer.add(new Label("Min reitingas"));
				poiFilterContainer.add(new Label("Rūšiuoti pagal:"));
				
				poiFilterPanel.add(poiFilterContainer);
				
			}
			
		});
		
		poiPanel.add(poiFilterPanel);
		
		
		return poiPanel;
		
	}
	
	/**
	 * Removes the map click handler.
	 */
	private void removeMapClickHandler() {
		if (newObjectHandlerAdded) {
			searchPoiByClickBtn.setEnabled(true);
			searchPoiByClickBtn.setText("Žymėti");
			map.removeMapClickHandler(addPoiMapHandler);
			newObjectHandlerAdded = false;
		}
	}

	/**
	 * Creates the filters panel.
	 * 
	 * @param panelHeight the panel height
	 * 
	 * @return the vertical panel
	 */
	private VerticalPanel createFiltersPanel(int panelHeight) {
		VerticalPanel filtersPanel = new VerticalPanel();
		ScrollPanel filtersCheckBoxPanel = new ScrollPanel();

		filtersCheckBoxPanel.setHeight(panelHeight + "px");
		filtersVerticalPanel = new VerticalPanel();

		filtersVerticalPanel.setSpacing(4);
		getPoiTypes();

		// TODO Disable when receiving objectTypeList
		Button ShowPoiBtn = new Button("Rodyti", new ClickHandler() {

			public void onClick(ClickEvent event) {
				int count = filtersVerticalPanel.getWidgetCount();
				List<String> filerList = new ArrayList<String>();
				for (int i = 0; i < count; i++) {
					CheckBox vp = (CheckBox) filtersVerticalPanel.getWidget(i);
					if (vp.getValue()) {
						filerList.add(vp.getName());
					}
				}

				// TODO should be true
				getPoi(filerList, true);

			}

		});
		Button CheckAllPoiBtn = new Button("Žymėti visus"); // turi pasikeisti i
		// "Nezymet"

		HorizontalPanel buttonsPanel = new HorizontalPanel();

		buttonsPanel.add(ShowPoiBtn);
		buttonsPanel.add(CheckAllPoiBtn);

		filtersCheckBoxPanel.add(filtersVerticalPanel);
		filtersPanel.add(buttonsPanel);
		filtersPanel.add(filtersCheckBoxPanel);

		return filtersPanel;
	}

	/** The routes list panel. */
	VerticalPanel routesListPanel = null;

	/**
	 * Creates the route panel.
	 * 
	 * @return the vertical panel
	 */
	private VerticalPanel createRoutePanel() {
		VerticalPanel routePanel = new VerticalPanel();
		routesListPanel = new VerticalPanel();

		getRoutes();
		routePanel.add(routesListPanel);

		return routePanel;

	}

	
	/**
	 * Gets the routes.
	 * 
	 * @return the routes
	 */
	private void getRoutes() {
		routesListPanel.clear();
		meniuW.showStack(1);
		if (route.getObjectsTime() != 0) {
			routesListPanel.add(new Label("Pasirinkite maršruto:"));
			HorizontalPanel btnPanel = new HorizontalPanel();

			addStartMapHandler = new MapClickHandler() {
				public void onClick(MapClickEvent event) {
					if (event.getOverlay() != null) {
						return;
					}
					addStartMarker(event.getLatLng());
					placeStartBtn.setEnabled(true);
					map.removeMapClickHandler(addStartMapHandler);
				}
			};
			addEndMapHandler = new MapClickHandler() {
				public void onClick(MapClickEvent event) {
					if (event.getOverlay() != null) {
						return;
					}
					addEndMarker(event.getLatLng());
					placeEndBtn.setEnabled(true);
					map.removeMapClickHandler(addEndMapHandler);
				}
			};
			
			placeStartBtn = new Button("Pradžią", new ClickHandler() {

				public void onClick(ClickEvent event) {
					placeStartBtn.setEnabled(false);
					//startHandlerAdded = true;
					map.addMapClickHandler(addStartMapHandler);
				}
			});
			placeEndBtn = new Button("Pabaigą", new ClickHandler() {

				public void onClick(ClickEvent event) {
					placeEndBtn.setEnabled(false);
					//endHandlerAdded = true;
					map.addMapClickHandler(addEndMapHandler);

				}

			});
			Button clearStartAndFinishButton = new Button("X", new ClickHandler(){

				public void onClick(ClickEvent event) {
					placeEndBtn.setEnabled(true);
					placeStartBtn.setEnabled(true);
					if(startMarker!= null)
					{
						
						map.removeOverlay(startMarker);
						startMarker = null;
					}
					if(endMarker != null)
					{
						
						map.removeOverlay(endMarker);
						endMarker = null;
					}
					getDirections();
					
				}
			
			});
			btnPanel.add(placeStartBtn);
			btnPanel.add(placeEndBtn);
			btnPanel.add(clearStartAndFinishButton);
			
			
			final Button makeRouteBtn = new Button("Gauti maršrutą",
					new ClickHandler() {
//TODO uzbaigti!!!
						public void onClick(ClickEvent event) {
							
							getDirections();




						}

					});
			routesListPanel.add(btnPanel);
			
			routesListPanel.add(new Label(
					"Pasirinktų objektų peržiūra užtruks apie: "
							+ route.getObjectsTime() + " min"));
			routesListPanel.add(new Label("Objektai sąraše:"));
			FlexTable flextable = new FlexTable();
			int i = 0;
			for (final ObjectSerializable o : route.getObjectList()) {
				flextable.setWidget(i, 0, new Label(o.getName()));
				flextable.setWidget(i, 1, new Button("X", new ClickHandler() {
					public void onClick(ClickEvent event) {
						route.removeObject(o);
						getRoutes();
					}
				}));
				i++;
			}
			routesListPanel.add(flextable);
			
			DisclosurePanel optionsPanel = new DisclosurePanel("Nustatymai");
			VerticalPanel tmpPanel = new VerticalPanel();
			tmpPanel.add(new Label("Pasirinkite keliavimo būdą:"));
			RadioButton optionsCarRadioButton = new RadioButton("travelOptions", "Mašina");
			RadioButton optionsWalkRadioButton = new RadioButton("travelOptions", "Pėsčiomis");
			tmpPanel.add(optionsCarRadioButton);
			tmpPanel.add(optionsWalkRadioButton);
			optionsPanel.add(tmpPanel);
			routesListPanel.add(optionsPanel);
			routesListPanel.add(makeRouteBtn);
		} else {
			routesListPanel
					.add(new Label(
							"Jūs neįtraukėte nei vieno objekto į savo maršrutą. Norėdami pasinaudoti maršruto sudarymo įrankiu pridėkite norimus apžiūrėti objektus."));
		}

	}
	 
	private void getDirections()
	{
		bounds = LatLngBounds.newInstance();
		ArrayList<Waypoint> points = new ArrayList<Waypoint>();
		if(startMarker != null)
		{
			//waypoints.
			points.add(new Waypoint(startMarker.getLatLng()));
		}
		for(ObjectSerializable o : route.getObjectList())
		{
			LatLng latlng = LatLng.newInstance(o.getLat(), o.getLng());
			points.add(new Waypoint(latlng));
		}
		if(endMarker != null)
		{
			//waypoints.
			points.add(new Waypoint(endMarker.getLatLng()));
		}
		
		waypoints = new Waypoint[points.size()];
		System.out.println("points.size() - "+points.size());
		int i = 0;
		for(Waypoint wp : points)
		{
			
			waypoints[i++] = wp;	
		}
		
		
		
		
		
		
		//setRetrievePolyline();
		DirectionQueryOptions options = new DirectionQueryOptions(null, directionsPanel);
		options.setRetrievePolyline(true);
		Directions.loadFromWaypoints(waypoints, options, new DirectionsCallback() {

			public void onFailure(int statusCode) {
				Window.alert("Nepavyko gauti keliavimo nurodymų iš serverio. Bandykite dar kartą.");
			}

			public void onSuccess(DirectionResults result) {
				// TODO Auto-generated method stub
				System.out.println("Valio");
				
				//TODO DirectionResults.getPolyline() returns null need to set DirectionQueryOptions.setRetrievePolyline(true);
				//map.clearOverlays();
				Polyline routePolyline = result.getPolyline();
				
				//TODO add beginning and end
				addMarkersToMap(route.getObjectList());
				if(startMarker!= null)
				{
					map.addOverlay(startMarker);
				}
				if(endMarker != null)
				{
					map.addOverlay(endMarker);
				}
				map.addOverlay(routePolyline);
				
				//map.clearOverlays();
				/*
				List<Route> routes = result.getRoutes();
				for(Route r : routes)
				{
					System.out.println(r.getNumSteps());
					for(int i = 0; i <r.getNumSteps(); i++)
					{
						System.out.println(r.getStep(i));
					}
					System.out.println(r.getSummaryHtml());
				}
				*/
			}
			
		});
	}

	/**
	 * Change main window.
	 * 
	 * @param window the window
	 */
	private void changeMainWindow(int window) {
		if (windowChange(window)) {
			currentMainWindow = window;
			switch (window) {
			// map
			case 0:
				menuAndMapPanel.remove(adminPanel);
				menuAndMapPanel.add(meniuW);
				menuAndMapPanel.add(map);

				break;

			// admin
			case 1:
				menuAndMapPanel.remove(meniuW);
				menuAndMapPanel.remove(map);
				menuAndMapPanel.add(adminPanel);

				break;
			default:
				break;
			}
		}
	}

	/**
	 * Window change.
	 * 
	 * @param window the window
	 * 
	 * @return true, if successful
	 */
	private boolean windowChange(int window) {
		if (currentMainWindow != window)
			return true;
		else
			return false;
	}

	/* (non-Javadoc)
	 * @see com.gidas.client.MapAdminListener#onChangeLayout()
	 */
	public void onChangeLayout() {
		// TODO refresh types
		getPoiTypes();
		changeMainWindow(0);

	}

	/**
	 * Check if logged in.
	 */
	public void checkIfLoggedIn() {
		LoginServiceAsync loginService = GWT.create(LoginService.class);
		loginService.login(GWT.getHostPageBaseURL(),
				new AsyncCallback<LoginInfo>() {
					public void onFailure(Throwable error) {
					}

					public void onSuccess(LoginInfo result) {
						loginInfo = result;
						if (loginInfo.isLoggedIn()) {
							loadLoggedInForm();
						} else {
							loadLoginForm();
						}
					}
				});

	}

	/**
	 * Load login form.
	 */
	private void loadLoginForm() {
		// Assemble login panel.
		signInLink.setHref(loginInfo.getLoginUrl());
		userInfoPanel.add(loginLabel);
		userInfoPanel.add(signInLink);
		if (RootPanel.get("userInfo").getWidgetCount() != 0) {
			RootPanel.get("userInfo").remove(0);
		}
		RootPanel.get("userInfo").add(userInfoPanel);
	}

	/**
	 * Load logged in form.
	 */
	private void loadLoggedInForm() {
		signOutLink.setHref(loginInfo.getLogoutUrl());
		String userNickname = loginInfo.getNickname();
		loginLabel.setText("Sveiki, " + userNickname + " ");
		userInfoPanel.add(loginLabel);
		userInfoPanel.add(signOutLink);
		if (RootPanel.get("userInfo").getWidgetCount() != 0) {
			RootPanel.get("userInfo").remove(0);
		}
		RootPanel.get("userInfo").add(userInfoPanel);
	}

}
